# user/views.py
import re
from datetime import datetime
from django.db.models import Q
from django.conf import settings
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.hashers import make_password
from django.contrib.auth.backends import ModelBackend

from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import viewsets
from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from rest_framework.permissions import DjangoModelPermissions
from django_filters.rest_framework import DjangoFilterBackend

from .models import UserProfile
from .filter import CheckUserFilter
from .serializer import UserProfileSerializer, CreateUserProfileSerializer, \
	UpdateUserProfileSerializer, UserProfileListSerializer
from utils.pagination import CustomPageNumberPagination
from utils.generics import ListAPIView, CreateAPIView, UpdateAPIView


# 登陆序列化
class LoginResponseSerializer(serializers.Serializer):
	status = serializers.BooleanField()
	user = UserProfileSerializer(many='error')
	isLogin = serializers.BooleanField()


# 通用序列化
class CommonResponseSerializer(serializers.Serializer):
	status = serializers.BooleanField()
	isLogin = serializers.BooleanField()


#邮箱和用户名都可以登录
# 基与ModelBackend类，因为它有authenticate方法
class CustomModelBackend(ModelBackend):
	def authenticate(self, request, username=None, password=None, **kwargs):
		print('username', username)
		print('password', password)
		try:
			user = UserProfile.objects.get(Q(username=username)|Q(email=username)|Q(mobile=username))
			if user.check_password(password):
				return user
		except Exception as e:
			return None


class LogInView(APIView):
	'''获取用户状态'''
	@swagger_auto_schema(
		title='获取用户状态',
		operation_description='获取用户状态',
		responses={200: LoginResponseSerializer})

	def get(self,request):
		# 解决react ie cookie禁用问题
		user = request.user
		if user.is_authenticated:
			user = UserProfileSerializer(instance=user)
			return Response({'status':'ok', 'user': user.data})
		return Response({'status':'error', 'msg':'用户未登录！'})


	params = openapi.Schema(type=openapi.TYPE_OBJECT, required=['username','password'], properties={
		'username': openapi.Schema(type=openapi.TYPE_STRING, description='用户名', examples='beta'),
		'password': openapi.Schema(type=openapi.TYPE_STRING, description='密码', examples='beta123'),
		})

	'''用户登录'''
	@swagger_auto_schema(
		title='用户登录',
		operation_description='用户登录',
		responses={200: LoginResponseSerializer},
		request_body=params)

	def post(self,request):
		data = request.data
		username = data.get('username', None)
		password = data.get('password', None)
		user = authenticate(username=username, password=password)
		if user is not None and user.is_active:
			login(request, user)
			user = UserProfileSerializer(instance=user)
			return Response({'status':'ok', 'user': user.data})
		else:
			return Response({'status':'error', 'msg':'用户名或密码错误！'})


class LogOutView(APIView):

	'''用户登出'''
	@swagger_auto_schema(
		title='logout',
		operation_description='用户登出')

	def get(self,request):
		logout(request)
		return Response({'status': 'error', 'msg':'登出成功'})


class CreateUserProfileView(CreateAPIView, GenericViewSet):

	'''创建用户'''
	filter_backends = [DjangoFilterBackend]
	queryset = UserProfile.objects.all()
	serializer_class = CreateUserProfileSerializer
	def create(self, request, *args, **kwargs):
		q = Q()
		q.connector = 'or'
		username = request.data['username']
		q.children.append(('username', username))
		try:
			mobile = request.data['mobile']
			if not re.match(settings.PATTERN_MOBILE,mobile):
				return Response({'status': 'error', 'msg': '手机号码格式不对'})
			q.children.append(('mobile', mobile))
		except:
			mobile = ''
		if username:
			try:
				user = UserProfile.objects.get(q)
			except:
				try:
					password = request.data['password']
				except:
					password = '123456'
				# _mutable = request.data._mutable
				# request.data._mutable = True
				request.data['password'] = make_password(password)
				request.data['is_active'] = True
				# request.data._mutable = _mutable
				return super().create(request, *args, **kwargs)
			return Response({'status': 'error', 'msg': '手机号或用户名已存在'})
		return Response({'status': 'error', 'msg': '异常参数,请检查是否正确输入'})


class UpdateUserProfileView(UpdateAPIView, GenericViewSet):

	'''修改用户'''
	filter_backends = [DjangoFilterBackend]
	queryset = UserProfile.objects.all()
	serializer_class = UpdateUserProfileSerializer
	def update(self, request, *args, **kwargs):
		try:
			mobile = request.data['mobile']
			if not re.match(settings.PATTERN_MOBILE,mobile):
				return Response({'status': 'error', 'msg': '手机号码格式不对'})
		except:
			pass
		try:
			user = UserProfile.objects.get(mobile=mobile)
		except:
			return super().update(request, *args, **kwargs)
		return Response({'status': 'error', 'msg': '手机号已存在'})


class ModifyPwdView(APIView):

	params = openapi.Schema(type=openapi.TYPE_OBJECT, required=['username','pwd1','pwd2'], properties={
		'username': openapi.Schema(type=openapi.TYPE_STRING, description='用户名', examples='beta'),
		'password1': openapi.Schema(type=openapi.TYPE_STRING, description='新密码', examples='beta123'),
		'password2': openapi.Schema(type=openapi.TYPE_STRING, description='重复密码', examples='beta123'),
		})

	'''修改用户密码'''
	@swagger_auto_schema(
		title='modify_pwd',
		operation_description='修改用户密码',
		responses={200: CommonResponseSerializer},
		request_body=params)
	def post(self, request):
		user = request.user
		data = request.data
		
		pwd1 = data.get('password1', '')
		pwd2 = data.get('password2', '')
		username = data.get('username', '')
		if not pwd1 or not username:
			return Response({'status':'error', 'msg': '信息不全！'})
		if user.username != username:
			return Response({'status':'error', 'msg': '违规操作！'})
		if pwd1 != pwd2:
			return Response({'status':'error', 'msg': '重复密码与密码不符！'})
		try:
			user = UserProfile.objects.get(username=username)
		except UserProfile.DoesNotExist:
			return Response({'status':'error', 'msg': '该用户不存在！'})
		user.password = make_password(pwd2)
		user.save()

		return Response({'status':'ok', 'msg': '修改用户密码成功！'})

class DeleteUserView(APIView):

	params = openapi.Schema(type=openapi.TYPE_OBJECT, required=['username','pwd1','pwd2'], properties={
		'username': openapi.Schema(type=openapi.TYPE_STRING, description='用户名', examples='1'),
		})

	'''删除用户'''
	@swagger_auto_schema(
		title='delete_user',
		operation_description='删除用户',
		responses={200: CommonResponseSerializer},
		request_body=params)
	def delete(self, request):
		data = request.data
		username = data.get('username', '')
		try:
			user = UserProfile.objects.get(username=username)
		except UserProfile.DoesNotExist:
			return Response({'status':'error', 'msg': '该用户不存在！'})
		UserProfile.objects.filter(username=username).delete()
		return Response({'status':'ok', 'msg': '删除成功！'})


class GetUserProfileListView(ListAPIView, GenericViewSet):

	"""获取所有用户"""
	queryset = UserProfile.objects.all()
	serializer_class = UserProfileListSerializer


class GetUserProfileByNameView(ListAPIView, GenericViewSet):

	"""根据名字搜索用户"""
	queryset = UserProfile.objects.all()
	serializer_class = UserProfileListSerializer
	filter_backends = (DjangoFilterBackend,)
	filter_class = CheckUserFilter